package com.gg.douyin.sdk.bean;

import com.alibaba.fastjson.JSONObject;
import com.gg.douyin.sdk.exception.DouyinException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * @author guiguan
 * @date 2019/12/11 19:47
 */
@Data
@Slf4j
public class DouyinConfigStorage {

    private volatile String openId;

    private volatile String clientKey;

    private volatile String scope;

    private volatile String redirectUri;

    private volatile String clientSecret;

    private static final String ACCESS_TOKEN_KEY = "douyin_access_token:";

    private static final String ACCESS_TOKEN_FIELD = "access_token";

    private static final String REFRESH_TOKEN_FIELD = "refresh_token";

    private final RedisTemplate<String, String> redisTemplate;

    public DouyinConfigStorage(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 获取accessToken
     *
     * @param openId 用户唯一id
     * @return accessToken
     */
    public String getAccessToken(String openId) {
        String jsonString = redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY.concat(openId));
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        return jsonObject.getString(ACCESS_TOKEN_FIELD);
    }

    /**
     * 获取refreshToken
     *
     * @param openId 用户唯一id
     * @return accessToken
     */
    public String getRefreshToken(String openId) {
        String jsonString = redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY.concat(openId));
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        return jsonObject.getString(REFRESH_TOKEN_FIELD);
    }

    /**
     * 存放accessToken
     *
     * @param openId      唯一识别码
     * @param accessToken accessToken
     * @param expressIn   过期时间
     */
    public void putAccessToken(String openId, String accessToken, String refreshToken, Integer expressIn) throws DouyinException {
        if (StringUtils.isBlank(accessToken)) {
            throw new DouyinException("accessToken为空");
        }
        if (StringUtils.isBlank(refreshToken)) {
            throw new DouyinException("refreshToken为空");
        }
        if (null == expressIn) {
            throw new DouyinException("expressIn为空");
        }
        if (StringUtils.isBlank(openId)) {
            throw new DouyinException("openId为空");
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put(ACCESS_TOKEN_FIELD, accessToken);
        jsonObject.put(REFRESH_TOKEN_FIELD, refreshToken);

        //此处为满足原子性，使用String类型数据结构
        redisTemplate.opsForValue().set(ACCESS_TOKEN_KEY.concat(openId), jsonObject.toJSONString(), expressIn, TimeUnit.SECONDS);

    }


    public boolean needRefreshToken(String openId) throws DouyinException {
        if (StringUtils.isBlank(openId)) {
            throw new DouyinException("openId is null");
        }
        Long expire = redisTemplate.getExpire(ACCESS_TOKEN_KEY.concat(openId));
        if (null == expire) {
            expire = 0L;
        }
        if (expire == -1) {
            log.warn("缓存未设置过期时间，openId:{}", openId);
        }
        //如果还有五天过期，则需要刷新
        return expire < 86400 * 5;
    }

}
